package com.njtoyo.taxi.admin.library.payment.jyb.util;

import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import lombok.extern.slf4j.Slf4j;

import java.io.UnsupportedEncodingException;
import java.lang.reflect.Method;
import java.util.*;

@Slf4j
public class JYBString {

    public static final String SUCCESS_CODE = "0000";

    public static String getSignVerify(String signStr, String keyPath, String keyPassword) {
        try {
            byte[] testByte = JYBCerts.sign(JYBCerts.getPrivateKey(keyPath, keyPassword), signStr.toString().getBytes("UTF8"));
            String base64 = new String(Base64.encode(testByte), "UTF-8");
            return base64.trim();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;

    }

    public static String getSignStr(Object bean) {
        Method[] methods = bean.getClass().getDeclaredMethods();
        List<String> valuesList = new ArrayList<String>();
        Map<String, String> keyMap = new TreeMap<String, String>(new Comparator<String>() {
            public int compare(String obj1, String obj2) {
                return obj2.compareTo(obj1);
            }
        });
        String version = "";
        for (Method method : methods) {
            String methodName = method.getName();
            if (methodName.startsWith("get") && !methodName.toLowerCase().contains("signature")) {
                Object value = null;
                try {
                    value = method.invoke(bean, new Object[]{});
                    if (value == null || "".equals(value.toString())) {
                        continue;
                    }
                } catch (Exception e) {
                }
                String key = methodName.substring(3, methodName.length());
                key = key.substring(0, 1).toLowerCase() + key.substring(1, key.length());
                if ("fileContent".equals(key)) {
                    value = (value == null ? "" : value.toString());
                    if (!"".equals(value)) {
                        value = MD5.toMD5(value.toString());
                    }
                } else if ("version".equals(key)) {
                    value = (value == null ? "" : value.toString());
                    version = value.toString();
                } else {
                    if (value instanceof String) {
                        value = (value == null ? "" : value);
                    } else if (value instanceof Double) {
                        value = (value == null ? "0" : value + "");
                    } else if (value instanceof Float) {
                        value = (value == null ? "0" : value + "");
                    } else if (value instanceof Integer) {
                        value = (value == null ? "0" : value + "");
                    }
                }

                keyMap.put(key, value.toString());
                valuesList.add(value.toString());
            }
        }

        StringBuffer merBuff = new StringBuffer();
        if ("2.0.0".equals(version)) {
            Set<String> keySet = keyMap.keySet();
            Iterator<String> keyI = keySet.iterator();
            while (keyI.hasNext()) {
                merBuff.append(keyMap.get(keyI.next()));
            }
        } else {
            Object[] strValues = (Object[]) valuesList.toArray();
            Arrays.sort(strValues);
            for (int i = 0; i < strValues.length; i++) {
                merBuff.append(strValues[i]);
            }
        }

        return merBuff.toString();
    }

    public static JsonObject stringToJson(String data) {
        String decoded = Base64.decode(data);
        Gson gson = new Gson();
        JsonElement element = gson.fromJson(decoded, JsonElement.class);
        return element.getAsJsonObject();
    }

    public static boolean parseRefundResponse(JsonObject object) {
        if (SUCCESS_CODE.equals(object.get("respCode").getAsString())) {
            return true;
        } else {
            log.info("Error code:" + object.get("respCode").getAsString() + " , Error Spec: " + object.get("respDesc").getAsString());
            return false;
        }
    }

}